#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
智能连接工具
针对8888端口连接问题的优化连接策略
"""

import socket
import time
import threading
import subprocess
import sys
import json
from datetime import datetime
import random

# 导入安全属性访问器
try:
    from core.safe_attribute_accessor import safe_getattr, safe_hasattr
except ImportError:
    # 如果导入失败，提供简单的备用实现
    def safe_getattr(obj, attr, default=None):
        return getattr(obj, attr, default)
    
    def safe_hasattr(obj, attr):
        return hasattr(obj, attr)

class SmartConnector:
    """智能连接器"""
    
    def __init__(self, target_ip="192.168.10.129", target_port=8888):
        self.target_ip = target_ip
        self.target_port = target_port
        self.connection_attempts = 0
        self.successful_connections = 0
        self.last_success_time = None
        self.connection_pattern = []
        self.running = False
        
    def log(self, message, level="INFO"):
        """日志记录"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        print(f"[{timestamp}] {level}: {message}")
    
    def test_connection(self, timeout=3):
        """测试单次连接"""
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(timeout)
            
            start_time = time.time()
            result = sock.connect_ex((self.target_ip, self.target_port))
            end_time = time.time()
            
            sock.close()
            
            self.connection_attempts += 1
            
            if result == 0:
                self.successful_connections += 1
                self.last_success_time = time.time()
                connection_time = (end_time - start_time) * 1000
                self.log(f"连接成功! 耗时: {connection_time:.2f}ms", "SUCCESS")
                return True, connection_time
            else:
                self.log(f"连接失败，错误码: {result}", "WARNING")
                return False, None
                
        except Exception as e:
            self.log(f"连接异常: {e}", "ERROR")
            return False, None
    
    def wait_for_service_restart(self):
        """等待服务重启的最佳时机"""
        # 根据您的日志，服务每5秒重启一次
        # 我们在服务刚启动后的1-2秒内尝试连接
        
        self.log("等待服务重启周期...")
        
        # 先等待当前周期结束
        time.sleep(2)
        
        # 然后在新周期开始后立即尝试
        for attempt in range(3):
            self.log(f"尝试连接 (第{attempt+1}次)")
            success, conn_time = self.test_connection(timeout=2)
            
            if success:
                return True
            
            # 如果失败，等待下一个周期
            time.sleep(5)
        
        return False
    
    def smart_connect_with_retry(self, max_attempts=20):
        """智能重试连接"""
        self.log(f"开始智能连接，最大尝试次数: {max_attempts}")
        
        for attempt in range(max_attempts):
            self.log(f"=== 连接尝试 {attempt + 1}/{max_attempts} ===")
            
            # 策略1: 直接尝试连接
            success, conn_time = self.test_connection()
            if success:
                self.log("直接连接成功!", "SUCCESS")
                return True
            
            # 策略2: 等待服务重启周期
            if self.wait_for_service_restart():
                self.log("周期性连接成功!", "SUCCESS")
                return True
            
            # 策略3: 随机延迟避免冲突
            delay = random.uniform(1, 3)
            self.log(f"等待 {delay:.1f} 秒后重试...")
            time.sleep(delay)
        
        self.log("所有连接尝试均失败", "ERROR")
        return False
    
    def establish_persistent_connection(self):
        """建立持久连接"""
        self.log("尝试建立持久连接...")
        
        max_retries = 50
        retry_count = 0
        
        while retry_count < max_retries:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(5)
                
                self.log(f"连接尝试 {retry_count + 1}/{max_retries}")
                result = sock.connect_ex((self.target_ip, self.target_port))
                
                if result == 0:
                    self.log("连接建立成功!", "SUCCESS")
                    
                    # 发送测试命令
                    test_commands = [
                        b"whoami\\n",
                        b"pwd\\n", 
                        b"id\\n"
                    ]
                    
                    for cmd in test_commands:
                        try:
                            self.log(f"发送命令: {cmd.decode().strip()}")
                            sock.send(cmd)
                            
                            # 等待响应
                            sock.settimeout(3)
                            response = sock.recv(1024)
                            
                            if response:
                                self.log(f"收到响应: {response.decode('utf-8', errors='ignore').strip()}", "SUCCESS")
                            else:
                                self.log("未收到响应", "WARNING")
                                
                            time.sleep(1)
                            
                        except socket.timeout:
                            self.log("响应超时", "WARNING")
                        except Exception as e:
                            self.log(f"命令执行异常: {e}", "ERROR")
                    
                    # 保持连接一段时间
                    self.log("保持连接30秒...")
                    time.sleep(30)
                    
                    sock.close()
                    self.log("连接已关闭")
                    return True
                
                else:
                    self.log(f"连接失败，错误码: {result}")
                    sock.close()
                
            except Exception as e:
                self.log(f"连接异常: {e}", "ERROR")
            
            retry_count += 1
            
            # 智能延迟策略
            if retry_count % 5 == 0:
                delay = 10  # 每5次失败后等待更长时间
            else:
                delay = random.uniform(3, 7)  # 随机延迟3-7秒
            
            self.log(f"等待 {delay:.1f} 秒后重试...")
            time.sleep(delay)
        
        self.log("无法建立持久连接", "ERROR")
        return False
    
    def monitor_target_service(self, duration=60):
        """监控目标服务状态"""
        self.log(f"开始监控目标服务 {duration} 秒...")
        
        start_time = time.time()
        connection_log = []
        
        while time.time() - start_time < duration:
            current_time = time.time()
            success, conn_time = self.test_connection(timeout=1)
            
            connection_log.append({
                "timestamp": current_time,
                "success": success,
                "connection_time": conn_time
            })
            
            if success:
                self.log(f"服务可用 (耗时: {conn_time:.2f}ms)", "SUCCESS")
            else:
                self.log("服务不可用", "WARNING")
            
            time.sleep(2)  # 每2秒检查一次
        
        # 分析连接模式
        self.analyze_connection_pattern(connection_log)
    
    def analyze_connection_pattern(self, connection_log):
        """分析连接模式"""
        self.log("分析连接模式...")
        
        successful_connections = [log for log in connection_log if log["success"]]
        total_attempts = len(connection_log)
        success_count = len(successful_connections)
        
        self.log(f"总尝试次数: {total_attempts}")
        self.log(f"成功次数: {success_count}")
        self.log(f"成功率: {(success_count/total_attempts)*100:.1f}%")
        
        if len(successful_connections) >= 2:
            # 计算成功连接之间的间隔
            intervals = []
            for i in range(1, len(successful_connections)):
                interval = successful_connections[i]["timestamp"] - successful_connections[i-1]["timestamp"]
                intervals.append(interval)
            
            if intervals:
                avg_interval = sum(intervals) / len(intervals)
                self.log(f"平均成功间隔: {avg_interval:.1f} 秒")
                
                if 4 <= avg_interval <= 6:
                    self.log("检测到5秒周期性模式", "INFO")
                    return "5_second_cycle"
        
        return "irregular"
    
    def optimized_connection_strategy(self):
        """优化的连接策略"""
        self.log("执行优化连接策略...")
        
        # 第一阶段：快速连接尝试
        self.log("阶段1: 快速连接尝试")
        for i in range(5):
            success, _ = self.test_connection(timeout=1)
            if success:
                return True
            time.sleep(1)
        
        # 第二阶段：周期性连接
        self.log("阶段2: 周期性连接尝试")
        for cycle in range(10):
            self.log(f"周期 {cycle + 1}/10")
            
            # 在每个5秒周期的开始尝试连接
            for offset in [0.5, 1.0, 1.5, 2.0]:
                time.sleep(offset)
                success, _ = self.test_connection(timeout=1)
                if success:
                    self.log(f"在周期偏移 {offset}s 时连接成功!", "SUCCESS")
                    return True
            
            # 等待下一个周期
            time.sleep(3)
        
        # 第三阶段：持续监控连接
        self.log("阶段3: 持续监控连接")
        return self.establish_persistent_connection()
    
    def generate_connection_report(self):
        """生成连接报告"""
        success_rate = (self.successful_connections / self.connection_attempts * 100) if self.connection_attempts > 0 else 0
        
        report = {
            "timestamp": datetime.now().isoformat(),
            "target": f"{self.target_ip}:{self.target_port}",
            "statistics": {
                "total_attempts": self.connection_attempts,
                "successful_connections": self.successful_connections,
                "success_rate": f"{success_rate:.1f}%",
                "last_success_time": self.last_success_time
            },
            "recommendations": self.get_recommendations()
        }
        
        report_file = f"smart_connection_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        try:
            with open(report_file, 'w', encoding='utf-8') as f:
                json.dump(report, f, indent=2, ensure_ascii=False)
            self.log(f"连接报告已保存: {report_file}")
        except Exception as e:
            self.log(f"保存报告失败: {e}", "ERROR")
        
        return report
    
    def get_recommendations(self):
        """获取改进建议"""
        success_rate = (self.successful_connections / self.connection_attempts * 100) if self.connection_attempts > 0 else 0
        
        recommendations = []
        
        if success_rate == 0:
            recommendations.extend([
                "目标服务可能未正确启动或配置有误",
                "检查目标服务器的防火墙设置",
                "验证目标服务的监听地址（0.0.0.0 vs 127.0.0.1）",
                "考虑使用其他端口或协议"
            ])
        elif success_rate < 30:
            recommendations.extend([
                "连接成功率极低，建议增加重试间隔",
                "实现智能退避算法",
                "考虑在服务重启周期内连接"
            ])
        elif success_rate < 70:
            recommendations.extend([
                "连接不稳定，建议优化连接时机",
                "实现连接状态监控",
                "添加连接保活机制"
            ])
        else:
            recommendations.append("连接状态良好，可以进行正常通信")
        
        return recommendations

def main():
    """主函数"""
    if len(sys.argv) > 1:
        target_ip = sys.argv[1]
    else:
        target_ip = "192.168.10.129"
    
    if len(sys.argv) > 2:
        target_port = int(sys.argv[2])
    else:
        target_port = 8888
    
    connector = SmartConnector(target_ip, target_port)
    
    print("=" * 60)
    print("🧠 智能连接工具")
    print(f"目标: {target_ip}:{target_port}")
    print(f"时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("=" * 60)
    
    # 选择执行模式
    if len(sys.argv) > 3:
        mode = sys.argv[3]
    else:
        mode = "smart"
    
    if mode == "monitor":
        connector.monitor_target_service(60)
    elif mode == "persistent":
        connector.establish_persistent_connection()
    else:
        # 默认智能连接模式
        success = connector.optimized_connection_strategy()
        if success:
            print("\n🎉 连接策略执行成功!")
        else:
            print("\n❌ 连接策略执行失败")
    
    # 生成报告
    connector.generate_connection_report()

if __name__ == "__main__":
    main()